﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using GameObjectsAndEquipment;
using GameObjectsAndEquipment.Weapons;
using LevelGenerator;


namespace StateMachine.GameStates
{
    public class GameplayState : GameState
    {
        LvlGenerator lvlGenerator;
        Level level;
        VampireRider player;
        SpriteFont font;
        Texture2D bulletTexture;
        Texture2D gunTexture;
        Texture2D machineGunTexture;
        Texture2D shotGunTexture;
        Texture2D mobTexture;
        Texture2D powerUpTexture;
        Texture2D ampouleTexture;
        Weapon weapon;
        ShotGun shotgun;
        Gun gun;
        MachineGun machinegun;
        List<Mob> mobs;
        List<Bullet> bulletsOnStage;
        List<ObjectPowerUp> powerUps;
        List<Item> items;
        float spawnTimer = 0;
        float gameTimer = 0;
        ObjectManager objectManager;

        int timer = 0;

        public GameplayState(int screenWidth, int screenHeight)
            : base(screenWidth, screenHeight)
        {
            lvlGenerator = new LvlGenerator(screenWidth, screenHeight);
            bulletsOnStage = new List<Bullet>();
            mobs = new List<Mob>();
            powerUps = new List<ObjectPowerUp>();
            items = new List<Item>();
        }

        public override void LoadContent(ContentManager content)
        {
            base.LoadContent(content);

            bulletTexture = content.Load<Texture2D>("bullet");
            font = content.Load<SpriteFont>("basic");
            gunTexture = content.Load<Texture2D>("gun");
            machineGunTexture = content.Load<Texture2D>("machinegun");
         // crossbowTexture = content.Load<Texture2D>("crossbow");
            shotGunTexture = content.Load<Texture2D>("shotgun");
            mobTexture = content.Load<Texture2D>("mob");
            powerUpTexture = content.Load<Texture2D>("powerUp");
            ampouleTexture = content.Load<Texture2D>("ampoule");
            level = lvlGenerator.GenerateLevel();
            player = new VampireRider(level.StartPoint, content.Load<Texture2D>("rect"));
            player.Equipment.Weapon = new Gun(Vector2.Zero, gunTexture,
                                                bulletTexture, player, bulletsOnStage);
            gun = new Gun(new Vector2(level.Rooms[1].Boundary.Center.X, level.Rooms[1].Boundary.Center.Y),
                                            gunTexture, bulletTexture, player,bulletsOnStage);
            shotgun = new ShotGun(new Vector2(level.Rooms[1].Boundary.Center.X, level.Rooms[1].Boundary.Center.Y),
                                            shotGunTexture, bulletTexture, player,bulletsOnStage);
            machinegun = new MachineGun(new Vector2(level.Rooms[1].Boundary.Center.X, level.Rooms[1].Boundary.Center.Y),
                                            machineGunTexture, bulletTexture, player, bulletsOnStage);

            objectManager = new ObjectManager(player, powerUps, bulletsOnStage, mobs,items);

            
        }

        public override void HandleInput(GameStateManager manager, GameTime gameTime)
        {
            base.HandleInput(manager, gameTime);

            KeyboardState newState = Keyboard.GetState();
            MouseState mouseState = Mouse.GetState();

            if (newState.IsKeyDown(Keys.E))
            {
                //manager.ExitGame();
                manager.PushState(new EquipmentState(screenWidth, screenHeight,player));
            }

         
            if (newState.IsKeyDown(Keys.D1)) // zmiana na gun
            {
                player.Equipment.ChangeWeapon(gun);
     
            }

            if (newState.IsKeyDown(Keys.D2)) // zmiana na machinegun
            {
               
                   player.Equipment.ChangeWeapon(machinegun);
            }

            if (newState.IsKeyDown(Keys.D3)) // zmiana na shotgun
            {
      
                   player.Equipment.ChangeWeapon(shotgun);
            }

            #region Player's input

            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                player.Shoot(new Vector2(mouseState.X, mouseState.Y));
            }

            
            Vector2 playerVelocity = Vector2.Zero;

            if (newState.IsKeyDown(Keys.W))
            {
                playerVelocity += new Vector2(0, -player.Speed);
            }
            if (newState.IsKeyDown(Keys.S))
            {
                playerVelocity += new Vector2(0, player.Speed);
            }
            if (newState.IsKeyDown(Keys.A))
            {
                playerVelocity += new Vector2(-player.Speed, 0);
            }
            if (newState.IsKeyDown(Keys.D))
            {
                playerVelocity += new Vector2(player.Speed, 0);
            }

            player.Velocity = playerVelocity;
            #endregion

            oldState = newState;
        }

        public override void Update(GameStateManager manager, GameTime gameTime)
        {
            timer += gameTime.ElapsedGameTime.Milliseconds;
            gameTimer += gameTime.ElapsedGameTime.Milliseconds;
            spawnTimer += gameTime.ElapsedGameTime.Milliseconds;
            HandleInput(manager, gameTime);

            base.Update(manager, gameTime);

            objectManager.Update();

            if (player.Hp <= 0)
            {
                manager.ChangeState(new EndGameState(screenWidth, screenHeight, gameTimer));
            }
            player.Update(gameTime);

            if (spawnTimer >= 1500)
            {
                Random r= new Random();
                Mob mob = new MobStandard(new Vector2(r.Next(600), r.Next(300)), mobTexture, new Gun(Vector2.Zero, gunTexture,
                                                bulletTexture, player, bulletsOnStage),player,powerUpTexture, ampouleTexture);
                mob.Weapon = new Gun(Vector2.Zero, gunTexture, bulletTexture, mob, bulletsOnStage, 9999, 2000);
                mobs.Add(mob);
                spawnTimer = 0;
            }

            for (int i = 0; i < mobs.Count; i++)
            {
                mobs[i].Update(gameTime);
            }

            #region bullets update

            for (int i = bulletsOnStage.Count - 1; i >= 0; i--)
            {
                bulletsOnStage[i].Update(gameTime);

                if (bulletsOnStage[i].X < -20 || bulletsOnStage[i].X > 1000
                    || bulletsOnStage[i].Y < -20 || bulletsOnStage[i].Y > 1000)
                {
                    bulletsOnStage.RemoveAt(i);
                }
            }

            #endregion



            #region temporary stuff
            if (weapon != null)
            {
                weapon.Update(gameTime);
                if (player.X > weapon.X && player.X < weapon.X + weapon.Width)
                {
                    if (player.Y > weapon.Y && player.Y < weapon.Y + weapon.Height)
                    {
                        player.Equipment.Weapon = weapon;
                        weapon = null;
                    }
                }
            }

            if (timer >= 5000)
            {
                Random rand = new Random();
                int n = rand.Next(level.Rooms.Count);
                switch (rand.Next(3))
                {
                    case 0:
                        weapon = new Gun(new Vector2(level.Rooms[n].Boundary.Center.X, level.Rooms[n].Boundary.Center.Y),
                                            gunTexture, bulletTexture, player, bulletsOnStage);
                        break;
                    case 1:
                        weapon = new MachineGun(new Vector2(level.Rooms[n].Boundary.Center.X, level.Rooms[n].Boundary.Center.Y),
                                            machineGunTexture, bulletTexture, player,bulletsOnStage);
                        break;
                    case 2:
                        weapon = new ShotGun(new Vector2(level.Rooms[n].Boundary.Center.X, level.Rooms[n].Boundary.Center.Y),
                                            shotGunTexture, bulletTexture, player,bulletsOnStage);
                        break;
                }
                timer = 0;
            }
            #endregion


        }

        public override void Draw(GameStateManager manager, GameTime gameTime)
        {
            base.Draw(manager, gameTime);

            #region Draw Level
            for (int i = 0; i < level.Rooms.Count; i++)
            {
                manager.Renderer.DrawRectangle(level.Rooms[i].Boundary, Color.Gray);
            }

            for (int i = 0; i < level.Corridors.Count; i++)
            {
               manager.Renderer.DrawRectangle(level.Corridors[i].Rect1, Color.Gray);
               manager.Renderer.DrawRectangle(level.Corridors[i].Rect2, Color.Gray);
            }
            #endregion

            #region Draw Bullets
            for (int i = 0; i <bulletsOnStage.Count; i++)
            {
                 manager.Renderer.DrawSprite(bulletsOnStage[i]);
            }

            for (int i = 0; i < mobs.Count; i++)
            {
                manager.Renderer.DrawSprite(mobs[i]);
            }

            for (int i = 0; i < powerUps.Count; i++)
            {
                manager.Renderer.DrawSprite(powerUps[i]);
            }

            for (int i = 0; i < items.Count; i++)
            {
                manager.Renderer.DrawSprite(items[i]);
            }

            #endregion

            if (weapon != null)
                manager.Renderer.DrawSprite(weapon);

            manager.Renderer.DrawSprite(player);

            //HUD

            manager.Renderer.DrawText(new TextObject(new Vector2(5,2),"Hp: " + player.Hp,font,Color.White), font);
        }



        private int CheckIfPlayerInRoom()
        {
            List<Room> rooms = level.Rooms;
            int roomIndex = -1;

            for (int i = 0; i < rooms.Count; i++)
            {
                Room room = rooms[i];
                if (player.X > room.Boundary.X && player.X + player.Width < room.Boundary.X + room.Boundary.Width)
                {
                    if (player.Y > room.Boundary.Y && player.Y + player.Height < room.Boundary.Y + room.Boundary.Height)
                    {
                        return i;
                    }
                }
            }

            return roomIndex;
        }
    }
}
